package com.tsd.base.service.impl;

import com.tsd.base.BaseCodeRuleConstants;
import com.tsd.base.dao.BaseRelatedPartyMapper;
import com.tsd.base.entity.BaseRelatedParty;
import com.tsd.base.entity.BaseRelatedPartyExt;
import com.tsd.base.service.BaseCodeRuleService;
import com.tsd.base.service.BaseRelatedPartyService;
import com.tsd.core.service.GetDuplicatedObj;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.ListUtil;
import com.tsd.core.vo.HlpException;
import com.tsd.core.vo.PageBean;
import com.tsd.service.BaseServiceImpl;
import com.tsd.system.entity.SysUser;
import com.tsd.system.utils.SysTreeUtil;
import com.tsd.core.thread.ThreadPoolTaskUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 描述：BaseRelatedParty 服务实现层
 *
 * @author david
 * @date 2024/03/26 15:24:49
 */
@Service
public class BaseRelatedPartyServiceImpl extends BaseServiceImpl implements BaseRelatedPartyService, GetDuplicatedObj {

    @Resource
    private BaseRelatedPartyMapper baseRelatedPartyMapper;
    @Resource
    private BaseCodeRuleService baseCodeRuleService;

    @Override
    public BaseRelatedParty getBaseRelatedPartyById(Long id) throws Exception {
        return baseRelatedPartyMapper.selectByPrimaryKey(id);
    }

    @Override
    public BaseRelatedPartyExt queryBySid(String sid) throws Exception {
        return baseRelatedPartyMapper.selectBySid(sid);
    }

    @Override
    public void deleteBaseRelatedPartys(List<String> list, SysUser opUser) throws Exception {
        for (String sid : list) {
            BaseRelatedParty old = baseRelatedPartyMapper.selectBySid(sid);
            super.checkEmpty(old, "该记录不存在");
            super.autoInjectBaseData(old, opUser, TYPE_DELETE);
            baseRelatedPartyMapper.updateByPrimaryKeySelective(old);
        }
    }

    @Override
    public boolean isDuplicated(Object params, String code) {
        if (params == null) {
            return false;
        }
        BaseRelatedPartyExt partyExt = (BaseRelatedPartyExt) params;
        partyExt.setCode(code);
        return baseRelatedPartyMapper.selectDuplicatedCode(partyExt) != null;
    }

    @Override
    public void saveBaseRelatedParty(BaseRelatedPartyExt record, SysUser opUser) throws Exception {
        if (HlpUtils.isEmpty(record.getSearch_code())){
            record.setSearch_code(HlpUtils.getPyinFirstLetter(record.getName()));
        }
        if (HlpUtils.isEmpty(record.getId())) {
            super.checkEmpty(record.getCode(), "请输入编码");
            super.checkEmpty(record.getName(), "请输入名称");
            if (!HlpUtils.isEmpty(record.getCode())) {
                //如果是手动设置了编号，则检查是否有相同的，有的话，置空后重新生成
                BaseRelatedPartyExt same = baseRelatedPartyMapper.selectDuplicatedCode(record);
                if (same != null) {
                    record.setCode(null);
                }
            }
            String genCode = baseCodeRuleService.genCode(null, BaseCodeRuleConstants.TYPE_RELATED_PARTY_CODE, BaseCodeRuleConstants.TYPE_NAME_RELATED_PARTY_CODE, opUser, record.getCode(), record, this);
            record.setCode(genCode);
            super.autoInjectBaseData(record, opUser, TYPE_CREATE);
            baseRelatedPartyMapper.insertSelective(record);
        } else {
            super.autoInjectBaseData(record, opUser, TYPE_UPDATE);
            baseRelatedPartyMapper.updateByPrimaryKeySelective(record);
        }
        this.setFullCode(record);
    }

    /**
     * 设置资源完整编码
     *
     * @param record
     */
    private void setFullCode(BaseRelatedParty record) {
        if (BaseRelatedPartyExt.REC_TYPE_DIRECTORY == record.getRec_type() && HlpUtils.isEmpty(record.getParent_sid())) {
            record.setFull_code(record.getId() + ".");
        } else {
            BaseRelatedPartyExt partyExt = baseRelatedPartyMapper.selectBySid(record.getParent_sid());
            if (partyExt != null) {
                record.setFull_code(partyExt.getFull_code() + record.getId() + ".");
            } else {
                record.setFull_code(record.getId() + ".");
            }
        }
        baseRelatedPartyMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public List<BaseRelatedPartyExt> findBaseRelatedPartys(Map<String, Object> params, PageBean page) throws Exception {
        return baseRelatedPartyMapper.selectByPage(params, page);
    }

    @Override
    public List<BaseRelatedPartyExt> findBaseRelatedPartys(Map<String, Object> params) throws Exception {
        return baseRelatedPartyMapper.selectByParams(params);
    }

    @Override
    public List<BaseRelatedPartyExt> findBaseRelatedPartyTypeTree(Map<String, Object> params) throws Exception {
        String parentSid = HlpUtils.getString(params, "parent_sid");
        if (!HlpUtils.isEmpty(parentSid)) {
            BaseRelatedPartyExt clientType = baseRelatedPartyMapper.selectBySid(parentSid);
            params.put("full_code", clientType.getFull_code() + "%");
        }
        params.remove("parent_sid");
        params.put("rec_type", 0);
        List<BaseRelatedPartyExt> list = baseRelatedPartyMapper.selectByParams(params);
        return SysTreeUtil.expandRelatedPartyTypeTree(list);
    }

    @Override
    public void importBaseRelatedPartys(List<BaseRelatedPartyExt> list, SysUser opUser) throws Exception {
        if (list == null || list.isEmpty()) {
            return;
        }
        // 检查Excel表格名称是否重复
        List<String> repeatList = list.stream().filter(item -> !HlpUtils.isEmpty(item.getName()))
                .collect(Collectors.groupingBy(BaseRelatedPartyExt::getName, Collectors.counting()))
                .entrySet().stream().filter(e -> e.getValue() > 1)
                .map(Map.Entry::getKey).collect(Collectors.toList());

        if (!HlpUtils.isEmptyList(repeatList)) {
            StringBuilder builder = new StringBuilder("（");
            String strDuplicatedName = String.join("、", repeatList);
            builder.append(strDuplicatedName);
            builder.append("）").append("Excel表格名称重复，请检查！");
            throw new HlpException(builder.toString());
        }
        // 检查导入数据是否系统是否已存在
        List<Integer> rec_type_list = new ArrayList<>(3);
        rec_type_list.add(BaseRelatedPartyExt.REC_TYPE_CLIENT);
        rec_type_list.add(BaseRelatedPartyExt.REC_TYPE_SUPPLIER);
        rec_type_list.add(BaseRelatedPartyExt.REC_TYPE_CLIENT_SUPPLIER);
        List<BaseRelatedPartyExt> clientExtList = ThreadPoolTaskUtil.queryInList4Split(list, splitList -> {
            Map<String, Object> params = new HashMap<>(3);
            params.put("dupList", splitList);
            params.put("dr", 0);
            params.put("rec_type_list", rec_type_list);
            return baseRelatedPartyMapper.selectByParams(params);
        });
        if (!HlpUtils.isEmptyList(clientExtList)) {
            StringBuilder builder = new StringBuilder("以下名称（");
            List<String> duplicatedNames = ListUtil.map(clientExtList, BaseRelatedPartyExt::getName);
            String strDuplicatedName = String.join("、", duplicatedNames);
            builder.append(strDuplicatedName);
            builder.append("）").append("记录已存在，请检查！");
            throw new HlpException(builder.toString());
        }
        for (BaseRelatedPartyExt partyExt : list) {
            if (BaseRelatedPartyExt.STATE_NAME_NONE_COOP.equals(partyExt.getState_name())) {
                partyExt.setState(BaseRelatedPartyExt.STATE_NONE_COOP);
            } else {
                partyExt.setState(BaseRelatedPartyExt.STATE_COOP);
            }
            if (BaseRelatedPartyExt.REC_TYPE_CLIENT_NAME.equals(partyExt.getRec_type_name())) {
                partyExt.setRec_type(BaseRelatedPartyExt.REC_TYPE_CLIENT);
            } else if (BaseRelatedPartyExt.REC_TYPE_CLIENT_SUPPLIER_NAME.equals(partyExt.getRec_type_name())) {
                partyExt.setRec_type(BaseRelatedPartyExt.REC_TYPE_SUPPLIER);
            } else {
                partyExt.setRec_type(BaseRelatedPartyExt.REC_TYPE_CLIENT_SUPPLIER);
            }
            this.saveBaseRelatedParty(partyExt, opUser);
        }
    }

    @Override
    public List<BaseRelatedPartyExt> findBaseRelatedPartyTypeTreeWithChildren(Map<String, Object> params) throws Exception {
        String parentSid = HlpUtils.getString(params, "parent_sid");
        BaseRelatedPartyExt rootObj = null;
        if (!HlpUtils.isEmpty(parentSid)) {
            rootObj = baseRelatedPartyMapper.selectBySid(parentSid);
            if (rootObj != null) {
                params.put("full_code_like", rootObj.getFull_code() + "%");
            }
        }
        params.remove("parent_sid");
        params.put("is_group", 1);
        List<BaseRelatedPartyExt> list = baseRelatedPartyMapper.selectByParams(params);
        Map<String, Object> client = new HashMap<>(2);
        client.put("dr", 0);
        client.put("is_group", 0);
        if (rootObj != null) {
            client.put("full_code_like", rootObj.getFull_code() + "%");
        }
        List<BaseRelatedPartyExt> clientExtList = baseRelatedPartyMapper.selectByParams(client);
        for (BaseRelatedPartyExt item : list) {
            List<BaseRelatedPartyExt> clientExts = ListUtil.filter(clientExtList, t -> !HlpUtils.isEmpty(t.getParent_sid()) && t.getParent_sid().equals(item.getSid()));
            item.setChildren(clientExts);
        }
        return SysTreeUtil.expandRelatedPartyTypeTree(list);
    }
}
